#!/usr/bin/env python3
# _*_ coding:utf-8 _*_
'''
1. 在测试视频(OpenCV安装目录\sources\samples\data)上，使用基于混合高斯模型的背景提取算法，提取前景并显示(显示二值化图像，前景为白色)。
2. 在1基础上，将前景目标进行分割，进一步使用不同颜色矩形框标记，并在命令行窗口中输出每个矩形框的位置和大小。
'''
import cv2 as cv
#加载视频
# Videofilename = r'D:\OpenCV-4.2.0-vc14_vc15\opencv\sources\samples\data\vtest.avi'
cap = cv.VideoCapture('vtest.avi')
if not cap.isOpened():
    print("无法打开视频文件")
fgbg = cv.createBackgroundSubtractorMOG2()

#在视频中做标记，封装成一个函数“labelTargets”
def labelTargets(img, mask, threshold):
    seg = mask.copy()
    cnts = cv.findContours(seg, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    count = 0
    for i in cnts[1]:
        area = cv.contourArea(i)
        if area < threshold:            #滤除面积小于threshold的分割结果，有可能为噪声
            continue
        count += 1
        rect = cv.boundingRect(i)
        print("矩形：X:{} Y:{} 宽：{} 高：{}".format(rect[0], rect[1], rect[2], rect[3]))
        cv.drawContours(img, [i], -1, (255, 255, 0), 1)
        cv.rectangle(img, (rect[0], rect[1]), (rect[0] + rect[2], rect[1] + rect[3]), (0, 0, 255), 1)
        cv.putText(img, str(count), (rect[0], rect[1]), cv.FONT_HERSHEY_PLAIN, 0.5, (0, 255, 0))
    return count

while True:
    flag, source = cap.read()
    if not flag:                           #未读到当前帧，结束
        break
    image = cv.pyrDown(source)
    fgMask = fgbg.apply(image)

    #kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))
    #morphImage_open = cv.morphologyEx(fgMask, cv.MORPH_OPEN, kernel, iterations=5)
    #mask = fgMask - morphImage_open
    _, Mask = cv.threshold(fgMask, 30, 0xff, cv.THRESH_BINARY + cv.THRESH_OTSU)
    targets = labelTargets(image, Mask, 30)

    print('共检测到',targets,'个目标' )
    backGround = fgbg.getBackgroundImage()
    foreGround = image - backGround
    cv.imshow('source', image)
    cv.imshow('background', backGround)
    cv.imshow('foreground', Mask)
    key = cv.waitKey(30)              #每一帧等待30ms
    if key == 27:                     #按“ESC”键退出
        break